﻿using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using Game.Map;
using Game.Map.Extensions;
using Game.Objects;
using MS.Utility;

namespace Game.Surface
{
    public class MoveVehicleAnamation
    {
        public event EventHandler Complete;
        
        readonly IMapField _Start;
        readonly IMapField _End;
        readonly Vehicle _Item;
        readonly GameCanvas _Canvas;
        readonly SurfaceControl _SurfaceControl;
        readonly Vehicle _Vehicle;

        Rectangle _Image;
        
        public MoveVehicleAnamation(
            SurfaceControl control,
            GameCanvas canvas,
            IMapField start,
            IMapField end,
            Vehicle item)
        {
            _SurfaceControl = control;
            _Canvas = canvas;
            _Start = start;
            _End = end;
            _Item = item;
            _Vehicle = item;
            Check();
        }
        
        public void Start()
        {
            var field = _SurfaceControl.Fields[
                new Point(_Start.Point.X, _Start.Point.Y)];
            var vfield = _SurfaceControl.GameMapView.ViewFields[
                new Point(_Start.Point.X, _Start.Point.Y)];
            double left = field.Left;
            double top = field.Top;

            var fieldEnd =_SurfaceControl.Fields[
                new Point(_End.Point.X, _End.Point.Y)];
            double leftEnd = fieldEnd.Left;
            double topEnd = fieldEnd.Top;

            var unitPicture = PlayerColorUpdater.GenerateImage(
                _Vehicle.Picture as BitmapImage, _Vehicle.Owner,
                (_Vehicle.Movement.Value > 0));

            NameScope.SetNameScope(_SurfaceControl, new NameScope());
 
            _Image = new Rectangle
            {
                Fill = new ImageBrush { ImageSource = unitPicture },
                Height = 100,
                Width = 100,
                StrokeThickness = 0,
                Stroke = new SolidColorBrush(Colors.Black)
            };

            GameCanvas.SetGameLeft(_Image, left);
            GameCanvas.SetGameTop(_Image, top);
            GameCanvas.SetZIndex(_Image, 1);
            
            _Canvas.Children.Add(_Image);

            var duration = new Duration(TimeSpan.FromSeconds(0.4));

            var a1 = new DoubleAnimation();
            var a2 = new DoubleAnimation();

            a1.From = left + 83;
            a2.From = top + 50;

            a1.Duration = duration;
            a2.Duration = duration;

            var sb = new Storyboard {Duration = duration};

            sb.Children.Add(a1);
            sb.Children.Add(a2);

            Storyboard.SetTarget(a1, _Image);
            Storyboard.SetTarget(a2, _Image);

            Storyboard.SetTargetProperty(a1, new PropertyPath(GameCanvas.GameLeftProperty));
            Storyboard.SetTargetProperty(a2, new PropertyPath(GameCanvas.GameTopProperty));
            
            a1.To = leftEnd + 83;
            a2.To = topEnd + 50;

            a1.Completed += OnComplete;

            string id = Guid.NewGuid().ToString();
            _SurfaceControl.Resources.Add(id, sb);
            
            sb.Begin();
        }

        void Check()
        {
            var vehicle = _Item;
            var path = new GamePath(_Start.Point, _End.Point);
            double moveAmount = path.CalcTerrainCost(_SurfaceControl.GameMapView);
            Debug.Assert(vehicle.Movement.Value >= moveAmount);
        }

        void OnComplete(object sender, EventArgs args) 
        {
            _Canvas.Children.Remove(_Image);

            var vehicle = _Item;
            Debug.Assert(vehicle != null, "vehicle != null");

            double origMovement = vehicle.Movement.Value;
            var path = new GamePath(_Start.Point, _End.Point);
            double moveAmount = path.CalcTerrainCost(_SurfaceControl.GameMapView);
            double newMovement = origMovement - moveAmount;
            vehicle.Movement.Decrease(moveAmount);

            if (Complete != null)
            {
                Complete(this, new EventArgs());
            }
        }
        
    }
}
